#!/bin/bash -e
#   * compile instructions: put this file in
#   *         `steamapps/common/Dyson Sphere Program/CustomMod`
#   * folder, open a terminal in the same folder, and execute:
#   *
#   * ```
#   *     chmod +x powerFull.cs
#   *     ./powerFull.cs
#   * ```
#   *
#   * then the mod will be compiled automatically.
#   *
#   * Here we wrote a shebang like file, which is correct
#   * in my computer (Manjaro XFCE), if such script do not work
#   * in your computer, you could just try the instructions below :

if [ -z "$__DOTNET_CSC" ]; then
    export __DOTNET_CSC="`find /usr/share/dotnet -type f -name dotnet` `find /usr/share/dotnet -name csc.dll`"
    echo '$'"__DOTNET_CSC not set yet, you should execute"
    echo "export __DOTNET_CSC='$__DOTNET_CSC'"
    echo "manually, or this alert will occur each time you execute this script."
fi

__MODE_VERBOSE=73 # is the line number of "#define VERBOSE", may be modified
__MODE_DEBUG__=$((__MODE_VERBOSE+1))
__MODE_RELEASE=$((__MODE_DEBUG__+1))

case $1 in
    V)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    v)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    VERBOSE) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    verbose) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    D)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    d)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    DEBUG)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    debug)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    *)       _MODE__SELECT_=$__MODE_RELEASE     ;;
esac

export GAME_NAME="觅长生"
export FILE_NAME="$0"

( yes "" | head -n $_MODE__SELECT_ | head -n-1  ; tail $FILE_NAME -n+$_MODE__SELECT_ ) | $__DOTNET_CSC -nologo -t:library \
  -r:'../BepInEx/core/BepInEx.dll' \
  -r:'../BepInEx/core/0Harmony.dll' \
  -r:"../${GAME_NAME}_Data/Managed/System.dll" \
  -r:"../${GAME_NAME}_Data/Managed/System.Core.dll" \
  -r:"../${GAME_NAME}_Data/Managed/UnityEngine.dll" \
  -r:"../${GAME_NAME}_Data/Managed/UnityEngine.CoreModule.dll" \
  -r:"../${GAME_NAME}_Data/Managed/mscorlib.dll" \
  -r:"../${GAME_NAME}_Data/Managed/Assembly-CSharp.dll" \
  -out:'../BepInEx/plugins/'"${FILE_NAME%.*}".dll \
  -optimize \
  -

if [ -n "$2" ]; then
    git add ${FILE_NAME}
    case $2 in
        R) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        r) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        RANDOM) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        random) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        U) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        u) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        UPLOAD) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        upload) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        *) git commit -am "$2" ;;
    esac
    git push
fi
exit

#define VERBOSE
#define DEBUG



using System;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

namespace Cheat
{
    [BepInPlugin("Neutron3529.Cheat", "Cheat", "0.1.1")]
    public class Cheat : BaseUnityPlugin {
        public static int extradraw=500;
        public static int extra_lundao_huihe=95;
        public static int extra_wudaodian=300;
        public static int read_book_time=0;
        public static int tupo_time=0;
        public static int ganwu_time=1;
#if DEBUG
        public static Action<string> logger;
#else
        public static void logger(string s){}
#endif
        void Start() {
            var harmony=new Harmony("Neutron3529.Cheat");
#if DEBUG
            logger=Logger.LogInfo;
#endif
            if (Config.Bind<bool>("config", "not_reduce_player_linggan", true, "论道后不减玩家灵感").Value){
                harmony.PatchAll(typeof(KBEngineAvatarReduceLingGanPatch));
                logger("Cheat-论道后不减玩家灵感 注入完成");
            }
            extradraw=Config.Bind<int>("config", "extra_draw_cards", 500, "额外抽卡").Value;
            if (Config.Bind<bool>("config", "recover_when_draw", true, "抽卡时恢复生命").Value){
                harmony.PatchAll(typeof(KBEngineAvatarNowDrawCardNum2Patch));
                logger("Cheat-抽卡+恢复生命值 注入完成，抽卡数+"+extradraw.ToString());
            }else if (extradraw>0){
                harmony.PatchAll(typeof(KBEngineAvatarNowDrawCardNumPatch));
                logger("Cheat-抽卡 注入完成，抽卡数+"+extradraw.ToString());
            }
            if ((read_book_time=Config.Bind<int>("config", "read_book_time", 1, "读书用时(设为-1禁用，设为0或许会引发异常，或许不会)").Value)!=-1){
                harmony.PatchAll(typeof(ToolsgetStudiSkillTimePatch));
                logger("Cheat-读书消耗时间="+read_book_time.ToString()+"天 注入完成");
            }
            if ((tupo_time=Config.Bind<int>("config", "tupo_time", 1, "突破用时(单位是月，设为-1禁用，设为0或许会引发异常，或许不会)").Value)!=-1){
                harmony.PatchAll(typeof(ToolsgetStudiStaticSkillTimePatch));
                logger("Cheat-突破消耗时间="+tupo_time.ToString()+"月 注入完成");
            }
            if ((ganwu_time=Config.Bind<int>("config", "ganwu_time", 1, "感悟用时（设为-1禁用，未测试设为0是否会导致游戏异常）").Value)!=-1){
                harmony.PatchAll(typeof(WuDaoMagCalcGanWuTimePatch));
                logger("Cheat-感悟时间="+ganwu_time.ToString()+"天 注入完成");
            }
            if (Config.Bind<bool>("config", "add_sixu_quality", true, "思绪至少为需感悟百年的六品（感悟百年是字面时间，因为Mod里面有一天感悟的补丁）").Value){
                harmony.PatchAll(typeof(WuDaoMagAddLingGuangPatch));
                logger("Cheat-思绪至少为需感悟百年的六品（感悟百年是字面时间） 注入完成");
            }
            if (Config.Bind<bool>("config", "rev_exchange_money", true, "反转道友交易的物品价值（未更改显示以及结算计算）").Value){
                harmony.PatchAll(typeof(ExchangePlanGetBuyMoneyPatch));
                logger("Cheat-反转道友交易的物品价值（未更改显示以及结算计算） 注入完成");
            }
            extra_wudaodian=Config.Bind<int>("config", "extra_wudaodian", 300, "论道获得额外悟道点(需启用“额外论道回合数”)").Value;
            if ((extra_lundao_huihe=Config.Bind<int>("config", "extra_lundao_huihe", 95, "额外论道回合数").Value)>5){
                harmony.PatchAll(typeof(LunDaoHuiHeInitPatch));
                logger("Cheat-额外论道回合数 注入完成，回合数+"+extra_lundao_huihe.ToString()+"，悟道点+"+extra_wudaodian.ToString());
            }
            if (Config.Bind<bool>("config", "force_change_play_fader", false, "强制更改全部进度条动画为提示信息（可能会引发不一致导致BUG）").Value){
                harmony.PatchAll(typeof(ToolsplayFaderForce));
                logger("Cheat-（作弊的）更改进度条动画为提示信息 注入完成");
            }else if (Config.Bind<bool>("config", "change_play_fader", true, "更改部分进度条动画为提示信息，可能会触发偶发BUG").Value){
                harmony.PatchAll(typeof(ToolsplayFaderPatch));
                logger("Cheat-（并不是作弊的）更改进度条动画为提示信息 注入完成");
            }
            if (Config.Bind<bool>("config", "not_AddNaiYao", true, "不增加耐药性").Value){
                harmony.PatchAll(typeof(itemAddNaiYaoXinPatch));
                logger("Cheat-不增加耐药性 注入完成");
            }
            if (Config.Bind<bool>("config", "lianqi_time", true, "炼器用时为0").Value){
                harmony.PatchAll(typeof(LianQiResultManagergetCostTimePatch));
                logger("Cheat-炼器时间为0 注入完成");
            }
            if (Config.Bind<bool>("config", "caiji_time", true, "采集(以及灵核采集)只有字面用时（影响收益）而实际用时为1月，同时增加字面收益 -- 这是最少的用时，因为游戏用一个BUG对“采集不耗时”这个修改做了检查……").Value){
                harmony.PatchAll(typeof(CaiJiCaiJiUIMagStartCaiJiPatch));
                harmony.PatchAll(typeof(CaiJiLingHeCaiJiUIMagStartCaiJiPatch));
            }
            /*
            if ((extra_wudao_value=Config.Bind<double>("config", "extra_wudao_value", 100.0, "额外悟道值乘数").Value)>0){
                harmony.PatchAll(typeof(itemAddNaiYaoXinPatch));
                logger("Cheat-额外悟道值乘数 注入完成");
                if (Config.Bind<bool>("config", "not_NPC", true, "额外悟道值乘数-NPC不享有额外悟道值乘数").Value){
                    harmony.PatchAll(typeof(itemAddNaiYaoXinPatch));
                    logger("Cheat-额外悟道值乘数-NPC不享有额外悟道值乘数 注入完成");
                }
            }*/
        }
        [HarmonyPatch(typeof(KBEngine.Avatar), "ReduceLingGan")]
        class KBEngineAvatarReduceLingGanPatch {
            public static bool Prefix(KBEngine.Avatar __instance) {
                return !__instance.isPlayer();
            }
        }
        [HarmonyPatch(typeof(KBEngine.Avatar), "NowDrawCardNum", MethodType.Getter)]
        class KBEngineAvatarNowDrawCardNumPatch {
            public static void Postfix(KBEngine.Avatar __instance, ref int __result) {
                if(__instance.isPlayer())__result+=extradraw;
            }
        }
        [HarmonyPatch(typeof(KBEngine.Avatar), "NowDrawCardNum", MethodType.Getter)]
        class KBEngineAvatarNowDrawCardNum2Patch {
            public static void Postfix(KBEngine.Avatar __instance, ref int __result) {
                if(__instance.isPlayer()){__result+=extradraw;__instance.HP=__instance.HP_Max;}
            }
        }
        [HarmonyPatch(typeof(Tools), "getStudiSkillTime")]
        class ToolsgetStudiSkillTimePatch {
            public static bool Prefix(ref int __result) {
                __result=read_book_time;
                return false;
            }
        }
        [HarmonyPatch(typeof(Tools), "getStudiStaticSkillTime")]
        class ToolsgetStudiStaticSkillTimePatch {
            public static bool Prefix(ref int __result) {
                __result=tupo_time;
                return false;
            }
        }
        [HarmonyPatch(typeof(KBEngine.WuDaoMag), "CalcGanWuTime")]
        class WuDaoMagCalcGanWuTimePatch {
            public static bool Prefix(ref int __result) {
                __result=ganwu_time;
                return false;
            }
        }
        [HarmonyPatch(typeof(KBEngine.WuDaoMag), "AddLingGuang")]
        class WuDaoMagAddLingGuangPatch {
            public static bool Prefix(ref int quality,ref int studyTime) {
                quality=Math.Max(quality,6);
                studyTime=Math.Max(studyTime,36500);
                return true;
            }
        }
        [HarmonyPatch(typeof(GUIPackage.ExchangePlan), "GetBuyMoney")]
        class ExchangePlanGetBuyMoneyPatch {
            public static void Postfix(ref int __result) {
                __result=-__result;
            }
        }
        [HarmonyPatch(typeof(LunDaoHuiHe), "Init")]
        class LunDaoHuiHeInitPatch {
            public static void Postfix(LunDaoHuiHe __instance) {
                __instance.totalHui+=extra_lundao_huihe;
                __instance.shengYuHuiHe+=extra_lundao_huihe;
                Tools.instance.getPlayer()._WuDaoDian += extra_wudaodian;
            }
        }
        [HarmonyPatch(typeof(Tools), "playFader")]
        class ToolsplayFaderPatch {
            public static bool Prefix(string content, UnityEngine.Events.UnityAction action=null) {
                if (action==null){
                    UIPopTip.Inst.Pop(content,PopTipIconType.任务完成); // 在这里调用action()会出现冲突：有一个refreshUI的action会因为调用过早而失效，这会导致我们可以错误地将功法在练气期点到第4层
                    return false;
                }else{return true;}
            }
        }
        [HarmonyPatch(typeof(Tools), "playFader")]
        class ToolsplayFaderForce {
            public static bool Prefix(string content, UnityEngine.Events.UnityAction action=null) {
                if (action!=null){
                    action();// 在这里调用action()会出现冲突：有一个refreshUI的action会因为调用过早而失效，这会导致我们可以错误地将功法在练气期点到第4层
                }
                UIPopTip.Inst.Pop(content,PopTipIconType.任务完成);
                return false;
            }
        }
        [HarmonyPatch(typeof(GUIPackage.item), "AddNaiYaoXin")]
        class itemAddNaiYaoXinPatch {
            public static bool Prefix() {
                return false;
            }
        }
        [HarmonyPatch(typeof(LianQiResultManager), "addLianQiTime")]
        class LianQiResultManagergetCostTimePatch {
            public static bool Prefix() {
                return false;
            }
        }
        [HarmonyPatch(typeof(CaiJi.CaiJiUIMag), "StartCaiJi")]
        public static class CaiJiCaiJiUIMagStartCaiJiPatch {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var res=new CodeMatcher(instructions).MatchForward(false,new CodeMatch(
                        OpCodes.Call,
                        AccessTools.Method(typeof(CaiJi.CaiJiUIMag), "GetCaiJiItemList"))
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_8),
                        new CodeInstruction(OpCodes.Shl)
                    ).InstructionEnumeration();
                res=new CodeMatcher(res).MatchForward(false,new CodeMatch(
                        OpCodes.Callvirt,
                        AccessTools.Method(typeof(KBEngine.Avatar), "AddTime"))
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Ldc_I4_0),
                        new CodeInstruction(OpCodes.Ldc_I4_1),
                        new CodeInstruction(OpCodes.Ldc_I4_0)
                    ).InstructionEnumeration();
                logger("Cheat-采集只需一月-Transpiler-CodeMatcher注入完成");
                return res;
            }
        }
        [HarmonyPatch(typeof(CaiJi.LingHeCaiJiUIMag), "StartCaiJi")]
        public static class CaiJiLingHeCaiJiUIMagStartCaiJiPatch {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var res=new CodeMatcher(instructions).MatchForward(false,new CodeMatch(
                        OpCodes.Call,
                        AccessTools.Method(typeof(CaiJi.LingHeCaiJiManager), "DoCaiJi"))
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_8),
                        new CodeInstruction(OpCodes.Shl)
                    ).InstructionEnumeration();
                res=new CodeMatcher(res).MatchForward(false,new CodeMatch(
                        OpCodes.Callvirt,
                        AccessTools.Method(typeof(KBEngine.Avatar), "AddTime"))
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Ldc_I4_0),
                        new CodeInstruction(OpCodes.Ldc_I4_1),
                        new CodeInstruction(OpCodes.Ldc_I4_0)
                    ).InstructionEnumeration();
                logger("Cheat-灵核采集只需一月-Transpiler-CodeMatcher注入完成");
                return res;
            }
        }/*
        [HarmonyPatch(typeof(LunDaoSuccess), "GetWuDaoZhi")]
        class LunDaoSuccessGetWuDaoZhiPatch {
            public static void Postfix(ref int __result) {
                __result=(int)(__result*extra_wudao_value);
            }
        }
        [HarmonyPatch(typeof(NpcSetField), "AddNpcWuDaoZhi")]
        class NpcSetFieldAddNpcWuDaoZhiPatch {
            public static bool Prefix(ref int value) {
                value=(int)(value/extra_wudao_value);
                return true;
            }
        }*/
    }
}

